#pragma once

#include <fstream>
#include <vector>
#include <string>
#include <map>
#include "as_def.hpp"

class Cvm {
    std::ifstream file;

    // 记录每个部分的类型和值
    struct Block {
        int type;
        union {
            double num;
            char* str;
            int direct;
        } value;
    };

    // 堆栈上的值
    enum Value_type {
        VALUE_NUM,
        VALUE_STR,
        VALUE_TABLE,
    };

    struct Value {
        Value_type type;

        union {
            double num;
            char* str;
            void* table;
        } value;
    };

    std::vector<Value> stack;

    // 函数栈，储存变量和返回地址
    struct Level {
        std::map<std::string, Value> vars;
        long return_addr;
    };

    std::vector<Level> fn_stack;
    std::map<std::string, long> label_msg;
    int code_long = 0;

    std::string read_str();
    Block read_block();
    Value& get_var_value(std::string var_name);
    void set_var_value(std::string var_name, Value& value);

public:
    void load_file(std::string filename);
    void execute();
};